package com.jia.netty;

import com.jia.netty.handler.ChartHandler;
import com.jia.netty.handler.CoonHandler;
import com.jia.netty.handler.HeardHandler;
import com.jia.netty.handler.WebSocketInChannelHandler;
import com.jia.service.ChatMessageService;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class StartWebSocketServer implements CommandLineRunner {

    @Value("${netty.port}")
    private Integer port;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private ChatMessageService messageService;

    /**
     * SpringBoot 初始化后调用
     * @param args
     * @throws Exception
     */
    @Override
    public void run(String... args) throws Exception {
        System.out.println("StartWebSocketServer...");
        EventLoopGroup master = new NioEventLoopGroup();
        EventLoopGroup slave = new NioEventLoopGroup();

        try {

            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(master,slave);
            bootstrap.channel(NioServerSocketChannel.class);
            bootstrap.childHandler(new ChannelInitializer() {
                @Override
                protected void initChannel(Channel channel) throws Exception {
                    ChannelPipeline pipeline = channel.pipeline();

                    pipeline.addLast(new HttpServerCodec());
                    pipeline.addLast(new HttpObjectAggregator(1024*10));

                    // 添加websocket的解编码器
                    pipeline.addLast(new WebSocketServerProtocolHandler("/"));

                    // 10s不发送消息自动断开
                    pipeline.addLast(new ReadTimeoutHandler(1, TimeUnit.HOURS));

                    // 添加处理客户端的请求的处理器
                    pipeline.addLast(new WebSocketInChannelHandler());

                    // 添加新连接的handler
                    pipeline.addLast(new CoonHandler(redisTemplate));

                    // 心跳的handler
                    pipeline.addLast(new HeardHandler());

                    // 发送消息的handler
                    pipeline.addLast(new ChartHandler(rabbitTemplate,messageService));


                }
            });

            ChannelFuture channelFuture = bootstrap.bind(port);
            channelFuture.sync();
            System.out.println("服务端启动成功");

        }catch (Exception e) {
            e.printStackTrace();
        }finally {

        }
    }
}
